package api

import (
	"context"

	"dev.ixmxm.top/rms/codes"
	"dev.ixmxm.top/rms/model"
	"dev.ixmxm.top/rms/utils/json"
	"dev.ixmxm.top/rms/utils/log"
)

// @Summary 自动门的启用和禁用
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body enableDoorParams true "自动门的启用和禁用"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 设备
// @Router /device/enable_door [post]
func (hg *HttpGateway) EnableDoor(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*enableDoorParams)
	err := hg.dispatcher.DM().EnableDoor(ctx, p.DeviceCode, p.Enable, p.MapName)
	if err != nil {
		log.Errorf("手动使能移动门%d 错误，设备编号:%s", p.Enable, p.DeviceCode)
		return nil, err
	}
	if p.Enable {
		hg.dispatcher.TRM().DeleteLockSiteFromDB(ctx, p.MapName, p.SiteId)
	} else {
		hg.dispatcher.TRM().AddLockSiteToDB(ctx, p.MapName, p.SiteId)
	}
	return nil, nil
}

// @Summary 获得所有电梯信息
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.Elevator "data数据：电梯信息集合"
// @Tags 设备
// @Router /device/get_elevators [get]
func (hg *HttpGateway) GetElevators(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	res, err := hg.dispatcher.DM().GetAllElevatorInfoFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all elevator info error:%s", err.UnWrapError())
		return nil, err
	}
	return res, nil
}

// @Summary 获得电梯信息
// @Description
// @Accept application/json
// @Produce application/json
// @Param device_code query string true "电梯信息编号"
// @Success 0 {object} ResponseExampleStruct "返回数据格式"
// @Success 1 {object} model.Elevator "data数据：电梯信息"
// @Tags 设备
// @Router /device/get_elevator [get]
func (hg *HttpGateway) GetElevator(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*elevatorCodeParams)
	res, err := hg.dispatcher.DM().GetElevatorFromDB(ctx, p.DeviceCode)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all elevator info error:%s", err.UnWrapError())
		return nil, err
	}
	if res == nil {
		return nil, codes.ErrDeviceNotExists
	}
	return res, nil
}

// @Summary 保存电梯信息
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body setElevatorParams true "电梯信息"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 设备
// @Router /device/save_elevator [post]
func (hg *HttpGateway) SaveElevator(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*setElevatorParams)
	//获得一键急停
	cfg := *hg.dispatcher.SystemConfig
	if !cfg.IsSoftStop {
		tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
		if len(tasks) > 0 {
			return nil, codes.ErrActionTaskExists
		}
	}
	return nil, hg.dispatcher.DM().AddElevatorToDB(ctx, p.DeviceCode, &p.Elevator)
}

// @Summary 保存电梯设备层信息
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body setElevatorLevelParams true "电梯层信息"
// @Success 0 {object} ResponseExampleStruct "返回数据格式"
// @Success 1 {object} model.Elevator "data数据：电梯信息"
// @Tags 设备
// @Router /device/save_elevator_level [post]
func (hg *HttpGateway) SaveElevatorLevel(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*setElevatorLevelParams)
	//获得一键急停
	cfg := *hg.dispatcher.SystemConfig
	if !cfg.IsSoftStop {
		tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
		if len(tasks) > 0 {
			return nil, codes.ErrActionTaskExists
		}
	}
	res, err := hg.dispatcher.DM().GetElevatorFromDB(ctx, p.DeviceCode)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all elevator info error:%s", err.UnWrapError())
		return nil, err
	}
	if res == nil {
		return nil, codes.ErrDeviceNotExists
	}
	if (res.ElevatorType == 0 && (p.Info.Door == model.ADoor || p.Info.Door == model.BDoor)) ||
		(res.ElevatorType == 1 && p.Info.Door == model.NormalDoor) {
		return nil, codes.ErrDeviceStatusNotMatch.WithDetails("电梯类型与层设置的开门方式不符")
	}
	isAny := false
	index := 0
	for i, info := range res.InfoList {
		if info.MapName == p.Info.MapName {
			isAny = true
			index = i
		}
	}
	if isAny {
		res.InfoList[index] = p.Info
	} else {
		return nil, codes.ErrDeviceNotExists.WithDetails("未找到对应配置信息")
		//res.InfoList = append(res.InfoList, p.Info)
	}
	err = hg.dispatcher.DM().AddElevatorToDB(ctx, p.DeviceCode, res)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// @Summary 添加电梯设备层信息
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body setElevatorLevelParams true "电梯层信息"
// @Success 0 {object} ResponseExampleStruct "返回数据格式"
// @Success 1 {object} model.Elevator "data数据：电梯信息"
// @Tags 设备
// @Router /device/add_elevator_level [post]
func (hg *HttpGateway) AddElevatorLevel(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*setElevatorLevelParams)
	//获得一键急停
	cfg := *hg.dispatcher.SystemConfig
	if !cfg.IsSoftStop {
		tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
		if len(tasks) > 0 {
			return nil, codes.ErrActionTaskExists
		}
	}
	res, err := hg.dispatcher.DM().GetElevatorFromDB(ctx, p.DeviceCode)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all elevator info error:%s", err.UnWrapError())
		return nil, err
	}
	if res == nil {
		return nil, codes.ErrDeviceNotExists
	}
	if (res.ElevatorType == 0 && (p.Info.Door == model.ADoor || p.Info.Door == model.BDoor)) ||
		(res.ElevatorType == 1 && p.Info.Door == model.NormalDoor) {
		return nil, codes.ErrDeviceStatusNotMatch.WithDetails("电梯类型与层设置的开门方式不符")
	}
	for _, info := range res.InfoList {
		if info.MapName == p.Info.MapName && info.StationId == p.Info.StationId && info.Door == p.Info.Door {
			return nil, codes.ErrDeviceExists.WithDetails("电梯类型与层设置的开门方式已存在")
		}
	}
	res.InfoList = append(res.InfoList, p.Info)
	err = hg.dispatcher.DM().AddElevatorToDB(ctx, p.DeviceCode, res)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// @Summary 删除电梯信息
// @Description
// @Accept application/json
// @Produce application/json
// @Param device_code query string true "电梯信息编号"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 设备
// @Router /device/delete_elevator [delete]
func (hg *HttpGateway) DeleteElevator(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*elevatorCodeParams)
	tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
	if len(tasks) > 0 {
		return nil, codes.ErrActionTaskExists
	}
	return nil, hg.dispatcher.DM().DeleteElevatorByDeviceCode(ctx, p.DeviceCode)
}

// @Summary 删除电梯设备层信息
// @Description
// @Accept application/json
// @Produce application/json
// @Param device_code query string true "电梯信息编号"
// @Param map_name query string true "地图名称"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 设备
// @Router /device/delete_elevator_level [delete]
func (hg *HttpGateway) DeleteElevatorLevel(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*elevatorLevelParams)
	tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
	if len(tasks) > 0 {
		return nil, codes.ErrActionTaskExists
	}
	res, err := hg.dispatcher.DM().GetElevatorFromDB(ctx, p.DeviceCode)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all elevator info error:%s", err.UnWrapError())
		return nil, err
	}
	if res == nil {
		return nil, codes.ErrDeviceNotExists
	}
	els := make([]model.ElevatorInfo, 0)
	for _, el := range res.InfoList {
		if el.MapName == p.MapName {
			continue
		}
		els = append(els, el)
	}
	res.InfoList = els
	err1 := hg.dispatcher.DM().AddElevatorToDB(ctx, p.DeviceCode, res)
	if err1 != nil {
		log.ErrorfWithContext(ctx, "modify current elevator err:%s", err1.UnWrapError())
		return nil, err1
	}
	return res, nil
}

// @Summary 强制释放电梯
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body releaseElevatorParams true "电梯信息编号"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 设备
// @Router /device/release_elevator [post]
func (hg *HttpGateway) ReleaseElevator(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*releaseElevatorParams)
	err := hg.dispatcher.DM().ModifyElevatorOccupyToDB(ctx, p.DeviceCode, "")
	if err != nil {
		log.Errorf("手动释放电梯错误DeviceCode:%s", p.DeviceCode)
		return nil, codes.ErrDeviceNotExists
	}
	return nil, nil
}

// @Summary 电梯的启用和禁用
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body enableElevatorParams true "电梯是否启用"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 设备
// @Router /device/enable_elevator [post]
func (hg *HttpGateway) EnableElevator(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*enableElevatorParams)
	err := hg.dispatcher.DM().EnableElevatorToDB(ctx, p.DeviceCode, p.Enable)
	if err != nil {
		log.Errorf("手动使能电梯%d错误，设备编号:%s", p.Enable, p.DeviceCode)
		return nil, err
	}
	return nil, nil
}

// @Summary 获取所有地图中所有电梯编号
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.DeviceCode "data数据：电梯编号集合"
// @Tags 设备
// @Router /device/get_map_elevator_codes [get]
func (hg *HttpGateway) GetMapElevatorCodes(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	elevatorCodes := make([]model.DeviceCode, 0)
	Add := func(deviceCode, mapName string) {
		isAny := false
		index := 0
		for i, elevatorCode := range elevatorCodes {
			if elevatorCode.DeviceCode == deviceCode {
				isAny = true
				index = i
			}
		}
		if isAny {
			elevatorCodes[index].MapNames = append(elevatorCodes[index].MapNames, mapName)
		} else {
			elevatorCodes = append(elevatorCodes, model.DeviceCode{DeviceCode: deviceCode, MapNames: []string{mapName}})
		}
	}

	maps, err := hg.dispatcher.TRM().GetAllMapFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all maps error:%s", err.UnWrapError())
		return nil, err
	}
	for _, m := range maps {
		mapData := &model.MapXml{}
		err := json.BindFromString(m.MapDataJsonString, mapData)
		if err != nil {
			return nil, codes.ErrMapConvert.WithDetails(err.Error())
		}
		for _, dot := range mapData.Dots {
			if dot.DeviceCode != "" && dot.Type == model.NodeElevator {
				Add(dot.DeviceCode, mapData.MapInfo.MapName)
			}
		}
	}
	return elevatorCodes, nil
}

// @Summary 获取所有地图中所有自动门编号
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.DeviceCode "data数据：自动门编号集合"
// @Tags 设备
// @Router /device/get_map_door_codes [get]
func (hg *HttpGateway) GetMapDoorCodes(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	doorCodes := make([]model.DeviceCode, 0)
	Add := func(deviceCode, mapName string) {
		isAny := false
		index := 0
		for i, doorCode := range doorCodes {
			if doorCode.DeviceCode == deviceCode {
				isAny = true
				index = i
			}
		}
		if isAny {
			doorCodes[index].MapNames = append(doorCodes[index].MapNames, mapName)
		} else {
			doorCodes = append(doorCodes, model.DeviceCode{DeviceCode: deviceCode, MapNames: []string{mapName}})
		}
	}

	maps, err := hg.dispatcher.TRM().GetAllMapFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all maps error:%s", err.UnWrapError())
		return nil, err
	}
	for _, m := range maps {
		mapData := &model.MapXml{}
		err := json.BindFromString(m.MapDataJsonString, mapData)
		if err != nil {
			return nil, codes.ErrMapConvert.WithDetails(err.Error())
		}
		for _, dot := range mapData.Dots {
			if dot.DeviceCode != "" && dot.Type == model.NodeAutoDoor {
				Add(dot.DeviceCode, mapData.MapInfo.MapName)
			}
		}
	}
	return doorCodes, nil
}
